home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
tcisam.zip
/
IWRITE.C
< prev
Wrap
Text File
|
1987-08-21
|
5KB
|
131 lines
/*
* IWRITE.C - write record.
*
* Copyright (c) 1987, Jim Mischel
* Modifications:
*
* 08/13/87 - jim - original coding
* 08/21/87 - jim - copy source to data buffer before writing
*/
#include "inxdefs.h"
/*
* iwrite() - add the data from '*source' to the data file. Returns 0 if
* successful, status on error. If duplicate keys are not permitted and
* adding the record would casue a duplicate key, the global variable 'ierrno'
* will be set to I_INVKEY.
*/
int iwrite(void *d, void *src)
{
df_rec *db_control = (df_rec *)d;
char *source = (char *)src;
inx_rec irec; /* new index record */
inx_rec save_inx_rec;
long save_inx_ptr,
write_pos;
irec.if_flags = 0;
switch (isearch(db_control,(source+db_control->df_key_offset))) {
case 0 :
if (!(db_control->df_flags & DF_DUP)) /* check duplicates */
return(ierror(I_INVKEY)); /* error: duplicate key */
/*
* duplicate record key.
* if the right node is a thread pointer, add the new record at right
*/
if (db_control->df_inx_buff.if_flags & RTHRD)
goto set_right;
/*
* otherwise get the inorder successor and add the new record as the
* left son.
*/
if (iget_next(db_control,&db_control->df_inx_buff)) {
return(ierrno);
}
case -1 : /* insert key at left node */
/* left node of new node is parent's left node */
irec.if_left_node = db_control->df_inx_buff.if_left_node;
/* right node of new node is parent */
irec.if_right_node = db_control->df_inx_ptr;
/* both right and left pointers of new node are thread pointers */
irec.if_flags = (db_control->df_inx_buff.if_flags & BTHRD) +
RTHRD + LTHRD;
/* if parent is the header node, this node is end of thread */
if (db_control->df_inx_ptr == 0L)
irec.if_flags |= ETHRD;
/* parent's left node points to new node */
db_control->df_inx_buff.if_left_node = fsize(db_control->df_inx_file);
/* parents left node is NOT a thread pointer */
db_control->df_inx_buff.if_flags &= (ETHRD+RTHRD);
break;
case 1 : /* insert key at right node */
set_right:
/* right node of new node is parent's right node */
irec.if_right_node = db_control->df_inx_buff.if_right_node;
/* left node of new node is parent */
irec.if_left_node = db_control->df_inx_ptr;
/* both right and left pointers of new node are thread pointers */
irec.if_flags = (db_control->df_inx_buff.if_flags & ETHRD) +
RTHRD + LTHRD;
/* parent's right node points to new node */
db_control->df_inx_buff.if_right_node = fsize(db_control->df_inx_file);
/* parent's right node is NOT a thread pointer */
db_control->df_inx_buff.if_flags &= (LTHRD+BTHRD);
break;
default : return(ierrno); /* read error */
} /* switch */
/* data record will go to end of data file */
irec.if_dat_ptr = fsize(db_control->df_dat_file);
/* new record's parent is current node */
irec.if_parent = db_control->df_inx_ptr;
/* save current index record */
memcpy(&save_inx_rec,&db_control->df_inx_buff,sizeof(inx_rec));
save_inx_ptr = db_control->df_inx_ptr; /* save current index pointer */
write_pos = fsize(db_control->df_inx_file); /* save new index location */
/*
* Now we update the index and data files. This is done as non-destructively
* as possible. The new index node is added to the index file first. Then
* the new data record is added to the end of the data file. The last
* operation performed is to update the old index record. This ensures
* the integrity of the binary tree structure. If an error occurs while
* writing any of the records, the binary tree remains as it was before
* adding the new node was attempted.
*/
/* add new index node */
if (iwrite_inx(db_control,&irec,write_pos))
return(ierrno);
/* add new data record to end of data file */
memcpy(db_control->df_dat_buff,source,db_control->df_rec_size);
if (iwrite_dat(db_control,source,fsize(db_control->df_dat_file)))
return(ierrno);
/* update the old index record */
if (iwrite_inx(db_control,&save_inx_rec,save_inx_ptr))
return(ierrno);
/* make index file point to new record */
if (iread_inx(db_control,write_pos))
return(ierrno);
db_control->df_flags &= ~DF_DELETE; /* clear deleted record flag */
return(ierror(0));
} /* iwrite */